<?php
/**
 * Utils library
 *
 * Contains various tools used throughout the site.
 * @package Packages
 */

/**
 *
 */
require_once(AD_SERVER_PATH . '/pkgs/init.php');
require_once(AD_SERVER_PATH . '/external/phRETS.php');
require_once(AD_SERVER_PATH . '/pkgs/crypter.php');
require_once(AD_SERVER_PATH . '/pkgs/logger.php');
require_once(AD_SERVER_PATH . '/pkgs/server.php');

/**
 * Utils library
 *
 * Contains various tools used throughout the site.
 * @package Packages
 */
class CUtils
{
	/**
	 * Get parameters
	 *
	 * Gets given parameters, parses and returns them.
	 * @param string $param_name
	 * @return string $param_val
	 */
	public static function get_param($param_name)
	{
		$param_val = null;
		if (isset($_GET[$param_name]))
		{
			$param_val = ($_GET[$param_name]);
		}
		else if (isset($_POST[$param_name]))
		{
			$param_val = ($_POST[$param_name]);
		}
		else //
		{
			$param_val = CUtils::get_cookie($param_name);
		}
		return CUtils::clean_string($param_val);
	}

	/**
	 * Cleanup string
	 *
	 * Takes in string, trims it, strips any trailing
	 * commas from the end, and returns it to caller.
	 * @param string $string
	 * @return string $string
	 */
	public static function clean_string($string)
	{
		if (!is_array($string))
		{
			$string = trim($string);
			$len = strlen($string);
			if (($len > 1) && ($string[$len -1] == ','))
			{
				$string = substr_replace($string, '', - 1);
			}
		}
		return $string;
	}

	/**
	 * Set cookie
	 *
	 * More info at http://www.php.net/manual/en/function.setcookie.php#84721
	 * @param string $name
	 * @param string $raw_value
	 * @param int $expires
	 */
	public static function set_cookie($name, $raw_value, $expires = 0)
	{
		$value = CCrypter::encrypt($raw_value);
		setcookie($name, $value, $expires);
	}

	/**
	 * Get cookie
	 *
	 * Checks if cookie is set, and if so decryts and returns it.
	 * @param string $key
	 * @return decrypted cookie | null
	 */
	public static function get_cookie($key)
	{
		if (isset($_COOKIE) && isset($_COOKIE[$key]))
		{
			return CCrypter::decrypt($_COOKIE[$key]);
		}
		else
		{
			CLogger::log('DEBUG', '', 'Failed to get cookie.');
			return null;
		}
	}

	/**
	 * Output error
	 *
	 * Outputs error to browser in XML.
	 * @param string $error
	 */
	public static function put_error($error)
	{
		CUtils::response_start_xml();
		echo('<results><error>' . $error . '</error></results>');
	}

	/**
	 * Get RETS object
	 *
	 * Creates, validates and returns RETS object.
	 * @param string $user
	 * @param string $pwd
	 * @return object $rets
	 */
	public static function get_rets($user, $pwd)
	{
		if (null == $user || null == $pwd)
		{
			CUtils::put_error('Please provide RETS username / password');
		}
		else //
		{
			$rets = new phRETS();
			$rets->AddHeader('Accept', '*/*');
			$rets->AddHeader('RETS-Version', AD_RETS_VERSION);
			$rets->AddHeader('User-Agent', AD_RETS_USER_AGENT);
			$rets->SetParam('debug_mode', AD_RETS_DEBUG_MODE);
			$rets->SetParam('cookie_file', AD_COOKIE_FOLDER.'/cookie_'.$user.'.txt');
			$rets->SetParam('debug_file', AD_DEBUG_FOLDER.'/rets_debug_'.$user.'.txt');
		}

		if(!is_object($rets))
		{
			CLogger::log('DEBUG', $user, 'RETS object creation error.');
			return null;
		}
		else if(TRUE != $rets->Connect(AD_RETS_URL, $user, $pwd))
		{
			CLogger::log('DEBUG', $user, 'RETS connection error.');
			return null;
		}
		return $rets;
	}

	/**
	 * Starts XML response
	 *
	 * Sets content type to XML and outputs XML version header.
	 */
	public static function response_start_xml()
	{
		header ('content-type: text/xml');
		echo '<?xml version="1.0" encoding="UTF-8" ?>';
	}

	/**
	 * Gets nice name for database fields
	 *
	 * Checks array and returns an AD approved field name.
	 * @param string $field
	 * @return string $field
	 */
	public static function get_standard_name($field)
	{
		$field = strtolower($field);
		$nice_name = array_search($field, $GLOBALS['MAP_RESULT_STD_NAME']);
		if (FALSE !== $nice_name)
		{
			return $nice_name;
		}
		else
		{
			return $field;
		}
	}

	/**
	 * Write file to server
	 *
	 * Locks file and writes contents to desired file.
	 * @param string $file_path
	 * @param string $contents
	 * @param char $mode
	 */
	public static function write_file($file_path, $contents, $mode)
	{
		$fh = fopen($file_path, $mode);
		if (flock($fh, LOCK_EX))
		{
			fwrite($fh, $contents);
			fflush($fh);
		}
		else
		{
			$msg = 'Could not get file lock, "' . $file_path . '" could not be written.';
			try
			{
				CLogger::log('ERROR', CCrypter::decrypt($_COOKIE['AD_RETS_U']), $msg);
			}
			catch (Exception $e)
			{
				echo $msg;
				return false;
			}
		}
		fclose($fh);
		return true;
	}
	
	/**
	 * Write file to server
	 *
	 * Locks file and writes contents to desired file.
	 * @param string $file_path
	 * @param array $contents
	 * @param char $mode
	 */
	public static function write_csv($file_path, $contents, $mode)
	{
		$fh = fopen($file_path, $mode);
		if (flock($fh, LOCK_EX))
		{
			 //fputcsv($fh, split(',', $content_array), ',', '&quot;');
			fputcsv($fh, $contents, ',');
			//fflush($fh);
		}
		else
		{
			$msg = 'Could not get file lock, "' . $file_path . '" could not be written.';
			try
			{
				CLogger::log('ERROR', CCrypter::decrypt($_COOKIE['AD_RETS_U']), $msg);
			}
			catch (Exception $e)
			{
				echo $msg;
				return false;
			}
		}
		fclose($fh);
		return true;
	}

	/**
	 * Create writable folders
	 *
	 * Creates all folders that are written to by server.
	 */
	public static function create_folders()
	{
		$folders  = array(AD_COOKIE_FOLDER, AD_DEBUG_FOLDER, AD_ACCESS_FOLDER, AD_TEMP_FOLDER, AD_USER_DATA_FOLDER) ; 
		foreach ($folders AS $folder)
		{
			if (!is_dir($folder))
			{
				if (FALSE === mkdir($folder, 0755, true))
				{
					echo(ERR_FOLDER_CREATE.' '. $folder .' ');
					die;
				}
			}
		}
	}

	/**
	 * XML packer
	 *
	 * Loops through array and packs it into XML.
	 * @param array $array
	 * @param string $tag
	 * @return string $output
	 */
	public static function pack_xml($array, $tag)
	{
		$output = '<' . $tag . '>' . PHP_EOL;
		foreach ($array AS $key => $val)
		{
			if (is_array($val))
			{
				$output .= CUtils::pack_xml($val, $key) . PHP_EOL;
			}
			else
			{
				$output .= '<' . htmlspecialchars($key) . '>' . htmlspecialchars($val, ENT_QUOTES) . '</' . htmlspecialchars($key) . '>' . PHP_EOL;
			}
		}
		$output .= '</' . $tag . '>';

		return $output;
	}

	/**
	 * Clean temp folder
	 *
	 * Cleans up images older than a day from temp folder.
	 */
	public static function clean_tmp_imgs()
	{
		$root_obj = dir(AD_TEMP_FOLDER);
		while ($img = $root_obj->read())
		{
			$create_date = date('Y-m-d', filemtime(AD_TEMP_FOLDER . $img));
			$todays_date = date('Y-m-d');

			if ($img != '.' && $img != '..' && $create_date != $todays_date)
			{
				unlink(AD_TEMP_FOLDER . $img);
			}
		}
		$root_obj->close();
	}

	/**
	 * Make temporary image
	 *
	 * Temporarily hold image for property matching passed MLS number and index.
	 * @param int $ml_number
	 * @param char $index
	 * @return array $files
	 */
	public static function mk_tmp_img($ml_number, $index)
	{
		CUtils::clean_tmp_imgs();

		$files = array();
		$server_obj = new CServer();
		$photos = $server_obj->get_img($ml_number, $index);

		foreach ($photos AS $photo)
		{
			if (true == $photo['Success'])
			{
				$file_name = md5(CUtils::get_param('AD_RETS_U') . $ml_number . $index . uniqid());
				$file_type = str_replace('image/', '.', trim($photo['Content-Type']));
				$file_path = AD_TEMP_FOLDER . $file_name . $file_type;

				CUtils::write_file($file_path, $photo['Data'], 'w');

				array_push($files, $file_path);
			}
		}
		return $files;
	}
}
